package com.woniuxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.entity.AllMenu;
import com.woniuxy.entity.DTO.MenuQueryDTO;
import com.woniuxy.entity.VO.MenuVO;
import com.woniuxy.mapper.MenuMapper;
import com.woniuxy.service.MenuService;
import com.woniuxy.util.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author pml
 * @Date 2025/7/15 11:58
 * @Description 菜单服务实现类
 * 实现菜单相关的业务逻辑
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, AllMenu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    /**
     * 获取侧边栏菜单树形结构
     * @return 树形结构的菜单列表
     */
    @Override
    public List<MenuVO> getSideMenu() {
        // 1. 查询所有菜单数据
        List<AllMenu> allMenuList = menuMapper.selectAllEnabledMenus();

        // 2. 转换为MenuVO并处理parentId为null的情况
        List<MenuVO> menuVOList = allMenuList.stream().map(allMenu -> {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(allMenu, menuVO);

            // 关键修复：将null的parentId转换为0（表示顶级菜单）
            // 避免后续处理时出现NullPointerException
            if (menuVO.getParentId() == null) {
                menuVO.setParentId(0);
            }
            return menuVO;
        }).collect(Collectors.toList());

        // 3. 构建树形结构
        return buildTree(menuVOList, 0);
    }

    /**
     * 递归构建菜单树形结构
     * @param menuList 所有菜单列表
     * @param parentId 父菜单ID
     * @return 树形结构的菜单列表
     */
    private List<MenuVO> buildTree(List<MenuVO> menuList, int parentId) {
        List<MenuVO> treeMenu = new ArrayList<>();

        for (MenuVO menu : menuList) {
            // 比较当前菜单的parentId与传入的parentId
            // 由于已处理null情况，此处可安全使用intValue()
            if (menu.getParentId().intValue() == parentId) {
                // 递归查找子菜单
                List<MenuVO> children = buildTree(menuList, menu.getMenuId());
                menu.setChildren(children);
                treeMenu.add(menu);
            }
        }
        return treeMenu;
    }

    /**
     * 分页多条件查询菜单列表
     * 支持复杂条件筛选，用于后台管理界面
     * @param queryDTO 查询条件和分页参数
     * @return 分页结果对象
     */
    @Override
    public PageResult<AllMenu> getMenuList(MenuQueryDTO queryDTO) {
        // 创建分页对象，设置当前页码和每页数量
        Page<AllMenu> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        // 创建查询条件构造器
        QueryWrapper<AllMenu> queryWrapper = new QueryWrapper<>();

        // 菜单标题模糊查询
        if (StringUtils.hasText(queryDTO.getMenuTitle())) {
            queryWrapper.like("menu_title", queryDTO.getMenuTitle());
        }

        // 路由路径模糊查询 - 添加此条件修复路由搜索问题
        // 前端传入的menuHref参数需要在这里处理才能生效
        if (StringUtils.hasText(queryDTO.getMenuHref())) {
            queryWrapper.like("menu_href", queryDTO.getMenuHref());
        }

        // 菜单状态精确查询
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }

        // 创建时间范围查询
        if (queryDTO.getCreateTimeStart() != null) {
            queryWrapper.ge("create_time", queryDTO.getCreateTimeStart());
        }
        if (queryDTO.getCreateTimeEnd() != null) {
            queryWrapper.le("create_time", queryDTO.getCreateTimeEnd());
        }

        // 按菜单ID升序排序，确保展示顺序一致
        queryWrapper.orderByAsc("menu_id");

        // 执行分页查询
        IPage<AllMenu> menuPage = menuMapper.selectPage(page, queryWrapper);

        // 封装分页结果
        PageResult<AllMenu> pageResult = new PageResult<>();
        pageResult.setPageNum(queryDTO.getPageNum());
        pageResult.setPageSize(queryDTO.getPageSize());
        pageResult.setTotal(menuPage.getTotal());
        pageResult.setPages((int) menuPage.getPages());
        pageResult.setList(menuPage.getRecords());

        return pageResult;
    }

    /**
     * 保存新菜单
     * 添加创建时间和创建人信息，默认创建人为admin
     * @param menu 菜单信息
     * @return 保存是否成功
     */
    @Override
    public boolean saveMenu(AllMenu menu) {
        // 设置创建时间为当前时间
        menu.setCreateTime(new Date());
        // 默认创建人为admin
        menu.setCreator("admin");
        return save(menu);
    }

    /**
     * 更新菜单信息
     * 添加更新时间和更新人信息，防止更新不存在的菜单
     * @param menu 菜单信息
     * @return 更新是否成功
     */
    @Override
    public boolean updateMenu(AllMenu menu) {
        // 检查菜单是否存在
        if (getById(menu.getMenuId()) == null) {
            return false;
        }
        // 设置更新时间为当前时间
        menu.setUpdateTime(new Date());
        // 默认更新人为admin
        menu.setUpdater("admin");
        return updateById(menu);
    }

    /**
     * 删除菜单
     * 采用逻辑删除，将状态改为0（禁用）而非物理删除
     * @param menuId 菜单ID
     * @return 删除是否成功
     */
    @Override
    public boolean deleteMenu(Integer menuId) {
        // 使用UpdateWrapper明确指定更新字段，避免null值覆盖
        UpdateWrapper<AllMenu> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("menu_id", menuId)
                .set("status", 0) // 仅更新状态为禁用
                .set("update_time", new Date())
                .set("updater", "admin");
        return update(updateWrapper);
    }

    @Override
    @Transactional
    public boolean batchDeleteMenu(List<Integer> menuIds) {
        UpdateWrapper<AllMenu> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("menu_id", menuIds)
                .set("status", 0)
                .set("update_time", new Date())
                .set("updater", "admin");
        return update(updateWrapper);
    }
}